package com.dt.core.tool.util;

import cn.hutool.core.util.IdUtil;
import com.dt.core.tool.enums.OsType;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;

/**
 * 高频方法集合类
 */
public class ToolUtil {


    public static String getUUID() {
        return IdUtil.simpleUUID();
    }

    public static void printRequestMap(HttpServletRequest request) {
        System.out.println("###################requst map#########################");
        Map<String, String[]> map = request.getParameterMap();
        System.out.println("url:" + request.getLocalAddr() + ":" + request.getLocalPort() + request.getRequestURI()
                + (map.size() > 0 ? "?" + request.getQueryString() : ""));
        System.out.println("uri:" + request.getRequestURI());
        System.out.println("addr:" + request.getLocalAddr());
        System.out.println("query:" + request.getQueryString());
        System.out.println("#####query####");
        for (String key : map.keySet()) {
            String values = "";
            for (int i = 0; i < map.get(key).length; i++) {
                values = map.get(key)[i] + " ## ";
            }
            System.out.println(key + ":" + values);
        }
        System.out.println("###################requst end#########################");
    }

    @SuppressWarnings("rawtypes")
    public static String get(Class cls) {
        String strURL = "";
        try {
            String strClassName = cls.getName();
            String strPackageName = "";
            if (cls.getPackage() != null) {
                strPackageName = cls.getPackage().getName();
            }
            String strClassFileName = "";
            if (!"".equals(strPackageName)) {
                strClassFileName = strClassName.substring(strPackageName.length() + 1);
            } else {
                strClassFileName = strClassName;
            }
            URL url = null;
            url = cls.getResource(strClassFileName + ".class");
            strURL = url.toString();
            strURL = strURL.substring(strURL.indexOf('/') + 1, strURL.lastIndexOf('/'));
            try {
                strURL = java.net.URLDecoder.decode(strURL, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            OsType os = OsType.getOSType();
            if (os == OsType.Windows) {
            } else if (os == OsType.Linux) {
                strURL = "/" + strURL;
            } else {
                strURL = "/" + strURL;
            }
        } catch (Exception c) {
        }
        return strURL;
    }

    public static String getRealPathInWebApp(String relativePath) {
        String path = get(ToolUtil.class);
        path = path.substring(0, path.indexOf("/WEB-INF/"));
        return path + "/" + relativePath;
    }

    public static String parseYNValue(String value) {
        if (value == null) {
            return value;
        }
        if (value.equals("Y")) {
            return "Y";
        }
        if (value.equals("N")) {
            return "N";
        }
        return value;
    }

    public static String parseYNValueDefN(String value) {
        if (value == null) {
            return "N";
        }
        if (value.equals("Y")) {
            return "Y";
        }
        if (value.equals("N")) {
            return "N";
        }
        return "N";
    }

    public static String parseYNValueDefY(String value) {
        if (value == null) {
            return "Y";
        }
        if (value.equals("Y")) {
            return "Y";
        }
        if (value.equals("N")) {
            return "N";
        }
        return "Y";
    }

    public static String getExceptionMsg(Exception e) {
        StringWriter sw = new StringWriter();
        try {
            e.printStackTrace(new PrintWriter(sw));
        } finally {
            try {
                sw.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        return sw.getBuffer().toString().replaceAll("\\$", "T");
    }

    /**
     * @Description 随机数字
     * @author fengshuonan
     */
    public static String getRandomNum() {
        return Calendar.getInstance().getTimeInMillis() + generateCellPhoneValNum();
    }

    /**
     * @Description 获取电话号码
     * @author fengshuonan
     */
    public static String generateCellPhoneValNum() {
        String[] beforeShuffle = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"};
        List<String> list = Arrays.asList(beforeShuffle);
        Collections.shuffle(list);
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            buffer.append(list.get(i));
        }
        String afterShuffle = buffer.toString();
        String result = afterShuffle.substring(3, 9);
        return result;
    }

    /**
     * 比较两个对象是否相等。<br>
     * 相同的条件有两个，满足其一即可：<br>
     * 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @return 是否相等
     */
    public static boolean equals(Object obj1, Object obj2) {
        return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
    }

    /**
     * 计算对象长度，如果是字符串调用其length函数，集合类调用其size函数，数组调用其length属性，其他可遍历对象遍历计算长度
     *
     * @param obj 被计算长度的对象
     * @return 长度
     */
    public static int length(Object obj) {
        if (obj == null) {
            return 0;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length();
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).size();
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).size();
        }
        int count;
        if (obj instanceof Iterator) {
            Iterator<?> iter = (Iterator<?>) obj;
            count = 0;
            while (iter.hasNext()) {
                count++;
                iter.next();
            }
            return count;
        }
        if (obj instanceof Enumeration) {
            Enumeration<?> enumeration = (Enumeration<?>) obj;
            count = 0;
            while (enumeration.hasMoreElements()) {
                count++;
                enumeration.nextElement();
            }
            return count;
        }
        if (obj.getClass().isArray() == true) {
            return Array.getLength(obj);
        }
        return -1;
    }

    /**
     * 对象中是否包含元素
     *
     * @param obj     对象
     * @param element 元素
     * @return 是否包含
     */
    public static boolean contains(Object obj, Object element) {
        if (obj == null) {
            return false;
        }
        if (obj instanceof String) {
            if (element == null) {
                return false;
            }
            return ((String) obj).contains(element.toString());
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).contains(element);
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).containsValue(element);
        }
        if (obj instanceof Iterator) {
            Iterator<?> iter = (Iterator<?>) obj;
            while (iter.hasNext()) {
                Object o = iter.next();
                if (equals(o, element)) {
                    return true;
                }
            }
            return false;
        }
        if (obj instanceof Enumeration) {
            Enumeration<?> enumeration = (Enumeration<?>) obj;
            while (enumeration.hasMoreElements()) {
                Object o = enumeration.nextElement();
                if (equals(o, element)) {
                    return true;
                }
            }
            return false;
        }
        if (obj.getClass().isArray() == true) {
            int len = Array.getLength(obj);
            for (int i = 0; i < len; i++) {
                Object o = Array.get(obj, i);
                if (equals(o, element)) {
                    return true;
                }
            }
        }
        return false;
    }


    //将all认定为emply
    public static boolean isNotEmptyWithAll(Object o) {
        Boolean v=!isEmpty(o);
        if(v){
            if("all".equals(o.toString())){
                return false;
            }
        }
        return v;
    }

    public static boolean isNotEmpty(Object o) {
        return !isEmpty(o);
    }

    @SuppressWarnings("rawtypes")
    public static boolean isEmpty(Object o) {
        if (o == null) {
            return true;
        }
        if (o instanceof String) {
            return o.toString().trim().equals("") || o.toString().length() == 0;
        } else if (o instanceof List) {
            return ((List) o).size() == 0;
        } else if (o instanceof Map) {
            return ((Map) o).size() == 0;
        } else if (o instanceof Set) {
            return ((Set) o).size() == 0;
        } else if (o instanceof Object[]) {
            return ((Object[]) o).length == 0;
        } else if (o instanceof int[]) {
            return ((int[]) o).length == 0;
        } else if (o instanceof long[]) {
            return ((long[]) o).length == 0;
        }
        return false;
    }

    /**
     * 对象组中是否存在 Empty Object
     *
     * @param os 对象组
     * @return
     */
    public static boolean isOneEmpty(Object... os) {
        for (Object o : os) {
            if (isEmpty(o)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 对象组中是否全是 Empty Object
     *
     * @param os
     * @return
     */
    public static boolean isAllEmpty(Object... os) {
        for (Object o : os) {
            if (!isEmpty(o)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否为数字
     *
     * @param obj
     * @return
     */
    public static boolean isNum(Object obj) {
        try {
            Integer.parseInt(obj.toString());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 如果为空, 则调用默认值
     *
     * @param str
     * @return
     */
    public static Object getValue(Object str, Object defaultValue) {
        if (isEmpty(str)) {
            return defaultValue;
        }
        return str;
    }

    /**
     * 强转->string,并去掉多余空格
     *
     * @param str
     * @return
     */
    public static String toStr(Object str) {
        return toStr(str, "");
    }

    /**
     * 强转->string,并去掉多余空格
     *
     * @param str
     * @param defaultValue
     * @return
     */
    public static String toStr(Object str, String defaultValue) {
        if (null == str) {
            return defaultValue;
        }
        return str.toString().trim();
    }


    public static int toInt(Object value) {
        return toInt(value, -1);
    }


    public static int toInt(Object value, int defaultValue) {
        return ConvertUtil.toInt(value, defaultValue);
    }


    public static long toLong(Object value) {
        return toLong(value, -1);
    }


    public static long toLong(Object value, long defaultValue) {
        return ConvertUtil.toLong(value, defaultValue);
    }

    // public static String encodeUrl(String url) {
    // return URLKit.encode(url, CharsetKit.UTF_8);
    // }
    //
    // public static String decodeUrl(String url) {
    // return URLKit.decode(url, CharsetKit.UTF_8);
    // }

    /**
     * map的key转为小写
     *
     * @param map
     * @return Map<String, Object>
     */

    public static Map<String, Object> caseInsensitiveMap(Map<String, Object> map) {
        Map<String, Object> tempMap = new HashMap<>();
        for (String key : map.keySet()) {
            tempMap.put(key.toLowerCase(), map.get(key));
        }
        return tempMap;
    }

    /**
     * 获取map中第一个数据值
     *
     * @param <K> Key的类型
     * @param <V> Value的类型
     * @param map 数据源
     * @return 返回的值
     */
    public static <K, V> V getFirstOrNull(Map<K, V> map) {
        V obj = null;
        for (Entry<K, V> entry : map.entrySet()) {
            obj = entry.getValue();
            if (obj != null) {
                break;
            }
        }
        return obj;
    }

    /**
     * 创建StringBuilder对象
     *
     * @return StringBuilder对象
     */
    public static StringBuilder builder(String... strs) {
        final StringBuilder sb = new StringBuilder();
        for (String str : strs) {
            sb.append(str);
        }
        return sb;
    }

    /**
     * 创建StringBuilder对象
     *
     * @return StringBuilder对象
     */
    public static void builder(StringBuilder sb, String... strs) {
        for (String str : strs) {
            sb.append(str);
        }
    }

    /**
     * 去掉指定后缀
     *
     * @param str    字符串
     * @param suffix 后缀
     * @return 切掉后的字符串，若后缀不是 suffix， 返回原字符串
     */
    public static String removeSuffix(String str, String suffix) {
        if (isEmpty(str) || isEmpty(suffix)) {
            return str;
        }
        if (str.endsWith(suffix)) {
            return str.substring(0, str.length() - suffix.length());
        }
        return str;
    }

    /**
     * 判断是否是windows操作系统
     *
     * @author stylefeng
     * @Date 2017/5/24 22:34
     */
    public static Boolean isWinOs() {
        String os = System.getProperty("os.name");
        return os.toLowerCase().startsWith("win");
    }

    /**
     * 获取临时目录
     *
     * @author stylefeng
     * @Date 2017/5/24 22:35
     */
    public static String getTempPath() {
        return System.getProperty("java.io.tmpdir");
    }

    public static void main(String[] args) {

    }
}
